<?php

OaTranslates::import('department');

use Phalcon\Mvc\Model\Behavior\SoftDelete;

class OaDepartments extends \Formax\Model
{

    const DELETED = 1;
    const NOT_DELETED = 0;

    /**
     *
     * @var integer
     */
    public $dept_id;

    /**
     *
     * @var string
     */
    public $department = '';

    /**
     *
     * @var integer
     */
    public $parent_id = 0;

    /**
     *
     * @var string
     */
    public $depth_path = '';

    /**
     *
     * @var integer
     */
    public $sort_order = 99;

    /**
     *
     * @var integer
     */
    public $deleted = 0;

    /**
     *
     * @var integer
     */
    public $ctime = 0;

    /**
     *
     * @var integer
     */
    public $mtime = 0;

    public function initialize()
    {
        $this->addBehavior(new SoftDelete(
            array(
                'field' => 'deleted',
                'value' => self::DELETED
            )
        ));
    }

    public function beforeUpdate()
    {
        // 获取新的路径
        if ($this->parent_id) {
            $parent = self::findFirst('dept_id=' . $this->parent_id);
            $this->depth_path = $parent->depth_path . $this->dept_id . ';';
        } else {
            $this->depth_path = $this->dept_id . ';';
        }

        // 查找以前旧的 parent_id，判断是否已经变更
        $self = self::findFirst('dept_id=' . $this->dept_id);
        if ($self->depth_path != $this->depth_path) {
            // 更新子类的路径
            $sql = "UPDATE " . $this->getSource() . " SET depth_path=REPLACE(depth_path, ?, ?) WHERE depth_path LIKE ?";
            $params = array($self->depth_path, $this->depth_path, $self->depth_path . '%');
            $this->getWriteConnection()->execute($sql, $params);
        }

        return parent::beforeUpdate();
    }

    // 在创建后，立即调用更新方法，以更新路径
    public function afterCreate()
    {
        $this->update();
    }

    // 删除操作
    public function delete()
    {
        // 删除子节点
        self::find('parent_id=' . $this->dept_id)->delete();

        // 删除部门角色
        // OaRoles::find('dept_id=' . $this->dept_id)->delete();

        // 删除部门用户
        // OaDepartmentUsers::find('dept_id=' . $this->dept_id)->delete();

        // 删除对应翻译
        // OaTranslates::find("keyword='department' and foreign_id={$this->dept_id}")->delete();
        return parent::delete();
    }

    // 获取所有的部门
    public static function getAll()
    {
        static $cached = null;

        if ($cached === null) {
            $rows = self::find(array(
                'deleted = 0',
                'order' => 'sort_order desc, dept_id asc'
            ))->toArray();

            $cached = array_using_key(self::_sort(0, $rows), 'dept_id');
        }

        return $cached;
    }

    // 获取部门信息
    public static function getOne($dept_id)
    {
        return array_get(self::getAll(), $dept_id);
    }

    // 对结果进行排序
    protected static function _sort($parent_id, array $rows)
    {
        $data = array();
        foreach ($rows as $row) {
            if ($row['parent_id'] == $parent_id) {
                $childs = self::_sort($row['dept_id'], $rows);
                $row['level'] = substr_count($row['depth_path'], ';') - 1;
                $row['is_parent']  = ! empty($childs);
                $data[] = $row;

                foreach ($childs as $child) {
                    $data[] = $child;
                }
            }
        }

        return $data;
    }

    // 获取所有的下级部门
    public static function getAllChilds($parent_id)
    {
        $all = self::getAll();

        if ($parent_id == 0) return $all;
        if (! $self = self::getOne($parent_id)) return array();
        return array_filter($all, function ($dept) use ($self) {
            return preg_match("~^{$self['depth_path']}(\d+;)+~", $dept['depth_path']);
        });
    }

    // 将路径转换为名称
    public static function path2name($path, $joined = false)
    {
        $all = self::getAll();
        $result = array();
        foreach (explode(';', trim($path, ';')) as $id) {
            if ($dept = array_get($all, $id, array())) {
                $dept['department'] = db_translate($dept['department'], 'department', $dept['dept_id']);
            }
            $result[] = array_get($dept, 'department');
        }

        if ($joined) {
            return implode(is_string($joined) ? $joined : '/', $result);
        }

        return $result;
    }

    // 判断是否父类
    public static function isParent($dept_id)
    {
        return count(self::getAllChilds($dept_id)) > 0;
    }

    // 统计部门人数
    public static function countUsers($dept_id)
    {
        $childs = array_pick(self::getAllChilds($dept_id), 'dept_id');
        array_push($childs, $dept_id);

        return OaDepartmentUsers::count('dept_id in (' . implode(',', $childs) . ')');
    }

}
